/*
   作者:selp
   qq:201228773
   完成时间:2021-7-21
   模仿官方的悬浮的日志框，
   增加了许多功能，和一些事件。
   其中引用了商店中发布的shape模块
   以美化界面
   悬浮窗有以下事件
   bear-move  窗口拖动时触发，会连续触发很多次
   ok  点击确定或按下回车触发，参数为输入的内容
   close 悬浮窗关闭时
   print 向控制台打印内容时，参数为打印的内容
   print-*  以*向控制台打印内容时，如log
   print-clear  控制台清空时
   show  悬浮窗显示完时
   hide  悬浮窗隐藏完时
    引入方法:
    const fl = new floatylog();
    setInterval(() => {}, 100);
    fl.log(params);
    fl.showDate();
    fl.showSign();
    fl.log('开始准备启动抖音');
 */


var shape = require("./drawable.js");


function bs(view, getWX, getHY, callback) {
    let x, y, x2, y2, time;
    let longClick;
    view.setOnTouchListener(function(view, event) {
        switch (event.getAction()) {
            case event.ACTION_DOWN:
                x = event.getRawX();
                y = event.getRawY();
                x2 = getWX();
                y2 = getHY();
                time = new Date().getTime();
                longClick = false;
                return true;
            case event.ACTION_MOVE:
                let time2 = new Date().getTime();
                if (!longClick && time2 > 1500) {
                    longClick = true;
                    view.emit('longClick');
                }
                let x1 = event.getRawX() + x2 - x;
                let y1 = event.getRawY() + y2 - y;
                callback(x1, y1, time2 - time);
                return true;
            case event.ACTION_UP:
                if (new Date().getTime() - time < 100) {
                    view.emit('click');
                }
                return true;
        }
        return true;
    });
}

function asyncEmit(event, eventName) {
    return Promise.resolve()
        .then(() => event.emit.apply(
            event, Array.prototype.slice.call(arguments, 1)))
}

function formatDate(date) {
    let sdf = new java.text.SimpleDateFormat('HH:mm:ss.SSS');
    return sdf.format(date);
}

const control = createWindow.prototype;
control.viewArr = [];
control.x = 0;
control.y = 100;
control.w = 600;
control.h = 400;
control.i = 100;
control.setPosition = function(x, y) {
    this.window.setPosition(x, y);
    this.x = x;
    this.y = y;
}
control.setSize = function(w, h) {
    let time = new Date().getTime();
    if (this.setSizeTime) {
        //设置调整悬浮大小的时间间隔，以免卡顿
        if (time - this.setSizeTime < 50) return false;
    }
    this.setSizeTime = time;
    this.window.setSize(w, h);
    this.w = w;
    this.h = h;
}
control.addView = function(data) {
    let text = data.text || "";
    let color = data.color || "#ffffff";
    if (this.showDate) {
        text = formatDate(new Date()) + data.sign + text;
    } else if (this.showSign) {
        text = data.sign + text;
    }
    ui.run(() => {
        let view = ui.inflate(
            `<text layout_gravity="center" padding="0"
                        marginBottom="0px" />`, this.window.content, false);
        view.setText(text);
        view.setTextColor(colors.parseColor(color));
        view.setTextSize(this.textSize || 13);
        this.window.content.addView(view);
        this.viewArr.push(view);
        setTimeout(() => {
            //添加完控件后不能立即滚动页面，需要等绘制到页面中后。
            this.window.scroll.fullScroll(android.widget.ScrollView.FOCUS_DOWN);
        }, 50);
        if (this.viewArr.length > (this.i)) this.delView();
    })
}
control.delView = function() {
    if (this.viewArr.length === 0) return false;
    ui.run(() => {
        this.window.content.removeView(this.viewArr.shift());
    });
}
control.clear = function(s) {
    let i = this.viewArr.length;
    let sid = setInterval(() => {
        if (i <= 0) {
            return clearInterval(sid);
        }
        i--;
        this.delView();
    }, s || 20);
}


function createWindow() {
    let window = floaty.rawWindow(
        `<frame id="vi" w="*" h="*" bg="#cc000000" padding="0 0 0 0" >
            <LinearLayout layout_width="match_parent" layout_height="match_parent" orientation="vertical">
                <LinearLayout padding="10 5 10 5" id="bart" bg="#ee000011" w="*" h="auto" margin="0" >
                    <text id="bear" text="脚本助手操作日志" textColor="#ffffff" layout_weight="1" />
                    <text w="auto" textColor="#FFFFFF" id="exit" text="关闭" padding="0" margin="0" />
                </LinearLayout>
                <ScrollView id="scroll" padding="0" margin="0" layout_weight="1">
                    <LinearLayout padding="2 0 2 0" id="content"  orientation="vertical">
                    </LinearLayout>
                </ScrollView>
                <LinearLayout w="*" h="auto" margin="0" padding="5 0 5 0" >
                    <input id="inp" maxLines = "1" padding="10 0 10 0" margin="0" layout_weight="1" />
                    <text w="auto" margin="3 0 0 0" textColor="#FFFFFF" text="确定" id="t7" padding="5" marginLeft="20" />
                </LinearLayout>
            </LinearLayout>
        </frame>`
    );
    window.exit.on('click', function() {
        window.close();
    });
    window.inp.on("touch_down", () => {
        window.requestFocus();
        window.inp.requestFocus();
    });
    window.inp.on("key", function(keyCode, event) {
        if (event.getAction() == 0 && keyCode == keys.back) {
            window.inp.clearFocus();
            window.disableFocus();
            event.consumed = true;
        }
    });
    window.t7.on("click", () => {
        window.inp.clearFocus();
        window.disableFocus();
    });
    shape.withGradientDrawable(context)
        .setColor("#cc000000")
        .setCornerRadii([20, 20, 20, 20, 5, 5, 5, 5])
        .into(window.vi);
    shape.withGradientDrawable(context)
        .setColors(["#6200ee", "#ef4e4f"])
        .setOrientation("tl_br")
        .setCornerRadius(5)
        .into(window.t7);
    shape.withGradientDrawable(context)
        .setColors(["#e46783", "#78c056f3"])
        .setCornerRadii([20, 20, 20, 20, 0, 0, 0, 0])
        .into(window.bart);
    shape.withLinearGradient(context)
        .setColors(["#6200ee", "#ef4e4f"])
        .setStrokeWidth(2)
        .setCornerRadius(30)
        .setOrientation("tl_br")
        .into(window.inp);
    let control = Object.create(createWindow.prototype);
    control.window = window;
    control.viewArr = [];
    window.setSize(control.w, control.h);
    window.setPosition(control.x, control.y);
    return control;
}

const suur = function () {
    //绑定events.emitter()
    events.__asEmitter__(this);
    this.control = createWindow();

    bs(this.control.window.bear, () => this.control.x, () => this.control.y, (x, y) => {
        if (x < 0) x = 0;
        if (x > device.width) x = device.width - 1;
        if (y < 0) y = 0;
        if (y > device.height) y = device.height - 1;
        this.control.setPosition(x, y);
        asyncEmit(this, 'bear-move', x, y);
    });
    bs(this.control.window.t7, () => this.control.w, () => this.control.h, (w, h, time) => {
        if (time < 2000) return;
        if (w < 400) w = 400;
        if (h < 500) h = 500;
        this.control.setSize(w, h);
    });
    this.control.window.t7.click(() => {
        asyncEmit(this, 'ok', this.control.window.inp.text());
        this.control.window.inp.text('');
    });
    this.control.window.exit.on('click', () => {
        asyncEmit(this, 'close');
    });
    this.control.window.inp.on("key", (keyCode, event) => {
        if (event.getAction() == 0 && keyCode == 66) {
            asyncEmit(this, 'ok', this.control.window.inp.text());
            this.control.window.inp.text('');
            event.consumed = true;
        }
    });

    //公开属性
    this.window = this.control.window;
    this.input = this.window.inp;
    this.butOk = this.window.t7;
    this.content = this.window.content;
    this.butColse = this.window.exit;
    this.title = this.window.bear;
}
suur.prototype.getContent = function(i) {
    if (i >= 0) {
        return this.control.viewArr[i].text();
    } else if (i < 0) {
        return this.control.viewArr[this.control.viewArr.length + i].text();
    } else {
        return this.control.viewArr.map((v) => v.text());
    }
}
suur.prototype.setMaxContent = function(i) {
    this.control.i = i;
}
suur.prototype.showSign = function(b) {
    this.control.showSign = b;
}
suur.prototype.showDate = function(b) {
    this.control.showDate = b;
}
suur.prototype.setTextSize = function(l) {
    if (!(l>0)) throw new Error('设置字体参数不合法');
    this.control.textSize = l;
}
suur.prototype.close = function() {
    this.control.window.exit.emit('click');
}
suur.prototype.log = function() {
    let text = util.format.apply(util, arguments);
    this.control.addView({
        text: text,
        color: "#ffffff",
        sign: "/D: "
    });
    asyncEmit(this, 'print-log', text);
    asyncEmit(this, 'print', text);
}
suur.prototype.info = function() {
    let text = util.format.apply(util, arguments);
    this.control.addView({
        text: text,
        color: "#64dd17",
        sign: "/I: "
    });
    asyncEmit(this, 'print-info', text);
    asyncEmit(this, 'print', text);
}
suur.prototype.verbose = function() {
    let text = util.format.apply(util, arguments);
    this.control.addView({
        text: text,
        color: "#c8c8c8",
        sign: "/V: "
    });
    asyncEmit(this, 'print-verbose', text);
    asyncEmit(this, 'print', text);
}
suur.prototype.warn = function() {
    let text = util.format.apply(util, arguments);
    this.control.addView({
        text: text,
        color: "#2962ff",
        sign: "/W: "
    });
    asyncEmit(this, 'print-warn', text);
    asyncEmit(this, 'print', text);
}
suur.prototype.error = function() {
    let text = util.format.apply(util, arguments);
    this.control.addView({
        text: text,
        color: "#d50000",
        sign: "/E: "
    });
    asyncEmit(this, 'print-error', text)
    asyncEmit(this, 'print', text);
}
suur.prototype.clear = function() {
    this.control.clear();
    asyncEmit(this, 'print-clear');
}

suur.prototype.hide = function() {
    if (this.control.hide) return false;
    let h = this.control.y + this.control.h + 200;
    this.control.hide = h;
    h = h / 100;
    let i = 0;
    let sid = setInterval(() => {
        this.control.setPosition(this.control.x, this.control.y - h);
        i++;
        if (i >= 100) {
            asyncEmit(this, 'hide');
            return clearInterval(sid);
        }
    }, 1);
}
suur.prototype.show = function() {
    if (!this.control.hide) return false;
    let h = this.control.hide;
    this.control.hide = undefined;
    h = h / 100;
    let i = 0;
    let sid = setInterval(() => {
        this.control.setPosition(this.control.x, this.control.y + h);
        i++;
        if (i >= 100) {
            asyncEmit(this, 'show');
            return clearInterval(sid);
        }
    }, 1);
}
export default suur;